﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Prism.Events;
using Reactor.Entities;
using Reactor.MiniManager.State;
using Reactor.MiniManager.ViewModels;
using Reactor.Providers;
using Samurai.Wakizashi.Workflow;

namespace Reactor.MiniManager.Workflows
{
    public class CoreStateCacheInitializationWorkflow : SequentialWorkflow<CoreStateCacheInitializationWorkflow.WorkflowContext>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="CoreStateCacheInitializationWorkflow"/> class.
        /// </summary>
        public CoreStateCacheInitializationWorkflow(ICoreDataProvider coreDataProvider, ICoreStateCache coreStateCache)
        {
            if (coreDataProvider == null) throw new ArgumentNullException("coreDataProvider");
            if (coreStateCache == null) throw new ArgumentNullException("coreStateCache");

            Context = new WorkflowContext { CoreDataProvider = coreDataProvider, CoreStateCache = coreStateCache };

            RegisterStep(ObtainCoreRecords, ThreadType.Task);
            RegisterStep(CreateCoreViewModels);
            RegisterStep(UpdateBindableCollectionWithCoreViewModels, ThreadType.Ui);
            RegisterStep(SusbscribeToHealthReports, ThreadType.Task);
            RegisterStep(StartCoreHealthCheckWorkflow);
        }

        #region Private Methods

        private void ObtainCoreRecords()
        {
            Context.Cores = Context.CoreDataProvider.GetAllCores();
        }

        private void CreateCoreViewModels()
        {
            var eventAggregator = Environment.Context.ServiceLocator.GetInstance<IEventAggregator>();
            Context.CoreViewModels = (from reactorCore in Context.Cores
                                      select new ReactorCoreViewModel(reactorCore, eventAggregator)).ToList();
        }

        private void UpdateBindableCollectionWithCoreViewModels()
        {
            foreach (var reactorCoreViewModel in Context.CoreViewModels)
                Context.CoreStateCache.ReactorCoreViewModels.Add(reactorCoreViewModel);
        }

        private void SusbscribeToHealthReports()
        {
            Context.CoreStateCache.SubscribeToServiceNotRespondingEvents();
        }

        private void StartCoreHealthCheckWorkflow()
        {
            Context.CoreStateCache.StartCoreHealthCheckWorkflow();
        }

        #endregion

        #region Nested Types

        public class WorkflowContext : IWorkflowContext
        {
            public ICoreStateCache CoreStateCache { get; set; }
            public ICoreDataProvider CoreDataProvider { get; set; }
            public IEnumerable<ReactorCoreEntity> Cores { get; set; }
            public List<ReactorCoreViewModel> CoreViewModels { get; set; }
        }

        #endregion
    }
}
